package com.scalar.chiptrack.operations.process.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.operations.process.ProcessStep;
import com.scalar.chiptrack.operations.process.Upload;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.process.dao.TestDAO;
import com.scalar.chiptrack.operations.process.dao.VendorLocationDAO;
import com.scalar.chiptrack.operations.process.dao.ProcessTrackDAO;
import com.scalar.chiptrack.operations.process.forms.TestForm;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.users.User;


public class TestAction extends ChipTrackAction {
    
    private static final String STEP_TYPE = "TEST";
    
    public ActionForward execute (ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) 
                                  throws Exception {
    
        String action = request.getParameter("action");
		HttpSession session = request.getSession();
        User user = (User)session.getAttribute (SessionKeys.USER_KEY);
		if (user == null)
		{
			return (mapping.findForward ("login"));
		}
		HashMap errors = new HashMap();
        if ((action != null) && (action.equalsIgnoreCase("save"))) 
        {
            TestForm testForm = (TestForm) form;
            DBTransaction dbTransaction = null;
            boolean success = false;
            
            int processStepId = -1;
			processStepId = testForm.getProcessStepId();
			             
			// added by ravikanth on 19 Aug 2003 to check for duplicate part numbers in Product Map Table
			String[] partNumbers = new String[testForm.getDupProductName().length+1];
			partNumbers[0] = testForm.getTestProductName();
			for(int i=0; i < testForm.getDupProductName().length ; i++)
			{
				partNumbers[i+1] = testForm.getDupProductName()[i];
			}
				
			// check for duplicates in Product_Map_Table
			String dupNames = ProductDao.checkDupInProductMapTable(partNumbers,processStepId,testForm.getStepName());
			if( dupNames.length() > 0 )
			{
				ArrayList vendorLocations = null;
				errors.put ("Part Numbers Already exists ", dupNames );
                vendorLocations = getAllVendorLocations( request );
                if(vendorLocations == null){
                    if(processStepId!=-1)
                    {
                        vendorLocations = VendorDAO.getTestLocations (processStepId);
                    }
                    else
                    {
                        vendorLocations = VendorDAO.getTestLocations ();
                    }
                }
				request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);
				request.setAttribute( "testForm" , testForm );
				request.setAttribute( "vendorLocations" , vendorLocations );
				return ( mapping.findForward("failure") );
			}
			// upto here
                
            try 
            {
				// start transaction 
				dbTransaction = DBTransaction.getInstance();
				dbTransaction.begin();
			
				ArrayList locations = getVendorLocations(request);

				if(processStepId==-1)
				{
					// Step 1
					// insert a record into Process_Step table and get the process step id
					processStepId = ProcessStep.getProcessStepID (dbTransaction, testForm.getStepName(), STEP_TYPE, testForm.getComments());
					
					// Step 2
					int procedureDocId = Upload.getProcedureDocID (dbTransaction, 
																	  STEP_TYPE, //TEST
																	  testForm.getProcedureDocNumber(), 
																	  testForm.getProcedureDocFile());

					// Step 3
					int programDocId = Upload.getProgramDocID (dbTransaction, 
																 STEP_TYPE, //TEST
																 testForm.getProgramDocNumber(), 
																 testForm.getProgramDocFile());
					// STEP 4
					// insert a row in Final_Test Table
					TestDAO.insertFinalTestRow (dbTransaction,
												  processStepId,
												  testForm.getLotHoldYieldLimit(),
												  testForm.getLotScrapYieldLimit(),
												  testForm.getTargetYield(),
												  testForm.getStandardUnitCost(),
												  testForm.getPoFrequency(),
												  procedureDocId,
												  programDocId,
												  testForm.getTestJig(),
												  testForm.getSystem());
					
					// Step 5
					// Store Product Table information
					ProductDao.saveProcessStepProduct (dbTransaction, 
											   processStepId, 
											   testForm.getTestProductName(), 
											   testForm.getBaseProductId());
					
					// Step 6
					// Update nextStepID in the previousStepID row
					ProductDao.updateNextProcessStepId (dbTransaction, testForm.getPreviousStepId(), processStepId);
					
					// Step 7
					// Save vendor locations
					
					if ((locations != null) && (locations.size() > 0)) 
					{
						VendorLocationDAO.saveVendorLocations (dbTransaction, processStepId, locations.iterator());
					}
					
					// Added by ravikanth on 19 Sep 2003 
					// Step 8
					// Save Duplicate names into Product_Map_Table
					if( testForm.getDupProductName() != null && testForm.getDupProductName().length > 0 )
					{
						ProductDao.saveProductMap( dbTransaction , processStepId , testForm.getDupProductName() , locations );
					}

                    // added by hareesh on 6th October 2003
                    // Step9
                    // Change Status from Incomplete -> InProcess
                    ProcessTrackDAO.updateTestTrack( dbTransaction, processStepId , testForm.getTrackId() , testForm.getStepName(), "Inprocess" );

				}
				else  // end of if productId != -1
				{ //Update Test Process

					//Step 1: Update Process Step Table	
					ProcessStep.updateProcessStepID(dbTransaction, testForm.getStepName(), STEP_TYPE, testForm.getComments(),processStepId);

					// Step 2
					int procedureDocId = Upload.getProcedureDocID (dbTransaction, 
																  STEP_TYPE, //TEST
																  testForm.getProcedureDocNumber(), 
																  testForm.getProcedureDocFile());

					// Step 3
					int programDocId = Upload.getProgramDocID (dbTransaction, 
															 STEP_TYPE, //TEST
															 testForm.getProgramDocNumber(), 
															 testForm.getProgramDocFile());

					// STEP 4
					// insert a row in Final_Test Table
					TestDAO.updateFinalTest (dbTransaction,
												  processStepId,
												  testForm.getLotHoldYieldLimit(),
												  testForm.getLotScrapYieldLimit(),
												  testForm.getTargetYield(),
												  testForm.getStandardUnitCost(),
												  testForm.getPoFrequency(),
												  procedureDocId,
												  programDocId,
												  testForm.getTestJig(),
												  testForm.getSystem());

					// Step 5
					// Update Product Table information
					ProductDao.updateProcessStepProduct (dbTransaction, 
											   processStepId, 
											   testForm.getTestProductName(), 
											   testForm.getBaseProductId());

					// Step 6
					// Save vendor locations
					VendorLocationDAO.deleteVendorLocations(dbTransaction,processStepId);
					if ((locations != null) && (locations.size() > 0)) 
					{
						VendorLocationDAO.saveVendorLocations (dbTransaction, processStepId, locations.iterator());
					}
					
					// Added by ravikanth on 19 Sep 2003 
					// Step 7
					// Save Duplicate names into Product_Map_Table
					if( testForm.getDupProductName() != null && testForm.getDupProductName().length > 0 )
					{
						ProductDao.saveProductMap( dbTransaction , processStepId , testForm.getDupProductName() , locations );
					}

				}
                // End transaction 
                success = true;
			}
            catch (Exception e) 
            {
                e.printStackTrace();
            }
            finally 
            {
                // Rollback or Commit the Transaction
                if (success == true) 
                {
                    dbTransaction.commit();
                }
                else 
                {
                    dbTransaction.rollback();
                }
            }
            
            // If sucessful, go to transport_locations page
            if (success == true) {
                
                request.setAttribute ("processStepId", processStepId+"");                     // 
                request.setAttribute ("previousStepId", testForm.getPreviousStepId()+"");   // 
                request.setAttribute ("binSetupEnabled", testForm.getBinSetupEnabled());    // used in Transport_Locations 
                request.setAttribute ("comingFrom", "TEST");                                  //
                
                request.setAttribute ("trackId", testForm.getTrackId()+"");                  // used in Tranport_Locations and Bin_Setup
                
                request.setAttribute ("stepName", testForm.getStepName());                   // used in Bin_Setup Action 
                request.setAttribute ("baseProductId", testForm.getBaseProductId()+"");     // 

                return (mapping.findForward("success"));
            }
            
            // else send the user back to test page
            ArrayList vendorLocations = getAllVendorLocations( request );
            if(vendorLocations == null){
                if(processStepId!=-1)
                    {
                        vendorLocations = VendorDAO.getTestLocations (processStepId);
                    }
                    else
                    {
                        vendorLocations = VendorDAO.getTestLocations ();
                    }
            }
            return (mapping.findForward("failure"));
        } // end of the if( action == save ) loop
        
        
        /*
         *  this part of the code is executed when action = null or action != SAVE 
         */
        int processStepId = Integer.parseInt (request.getParameter ("processStepID"));
        int trackId = -1;
        String trackIdStr = request.getParameter ("trackID");
        
        if ((trackIdStr != null) && (trackIdStr.trim().length() != 0)) 
        {
            trackId = Integer.parseInt (trackIdStr);
        }
        
        String binSetupEnabled = request.getParameter ("binSetup"); // true or false
        
	    if (binSetupEnabled == null) binSetupEnabled = "false";
        
        TestForm testForm = null;
        ArrayList vendorLocations = null;
        
        //System.out.println("My Process Id in TestAction   "+ processStepId);
        
        if (processStepId == -1) {  // New 
        
            String stepName = request.getParameter ("stepName");
            String testProductName = request.getParameter ("productName");
            int baseProductId = Integer.parseInt (request.getParameter ("baseProductID"));
            int previousStepId = Integer.parseInt (request.getParameter ("previousStepID"));
            
            testForm = TestDAO.loadTestProcessData (previousStepId);
            if (testForm == null) {
                testForm = new TestForm();
            }
            
            testForm.setStepName (stepName);
            testForm.setTestProductName (testProductName);
            testForm.setBaseProductId (baseProductId);
            testForm.setPreviousStepId (previousStepId);
            testForm.setTrackId (trackId);
            testForm.setBinSetupEnabled (binSetupEnabled);    
            
            vendorLocations = VendorDAO.getTestLocations();
        }
        else 
        {  // Existing
            testForm = TestDAO.loadTestProcessData (processStepId);
            testForm.setTrackId (trackId);
            testForm.setProcessStepId (processStepId);
			testForm.setBinSetupEnabled (binSetupEnabled);
            vendorLocations = VendorDAO.getTestLocations (processStepId);
        }
        
        request.setAttribute ("vendorLocations", vendorLocations);
        request.setAttribute ("testForm", testForm);

        return (mapping.findForward("show"));
    }

    
    private ArrayList getVendorLocations (HttpServletRequest request) {
        
        ArrayList vendorLocations = new ArrayList();
        
        String[] locationName = request.getParameterValues("locationName");
        if (locationName == null) {
            return null;
        }
        
		String[] priority = request.getParameterValues("priority");
		String[] locationID = request.getParameterValues("locationID");;
		String[] split = request.getParameterValues("split");
		String[] capacityWeek = request.getParameterValues("capacityWeek");
		String[] normalCost = request.getParameterValues("normalCost");
		String[] expressCost = request.getParameterValues("expressCost");
		String[] normalCycleTime = request.getParameterValues("normalCycleTime");
		String[] expressCycleTime = request.getParameterValues("expressCycleTime");

        VendorLocation location = null;
        String select = null;
        
        for (int i=0; i<locationName.length; i++) {

            select = request.getParameter("select_"+i);
            if (select != null) {    // check if this row was enabled by the user or not
                                     // save only if its enabled
                
                // Changed by hareesh on 25th August 2003
                // -- START --
                /*location = new VendorLocation (priority[i],
                                                 locationName[i],
                                                 locationID[i],
                                                 split[i],
                                                 capacityWeek[i],
                                                 Float.parseFloat(normalCost[i]),
                                                 Float.parseFloat(expressCost[i]),
                                                 normalCycleTime[i],
                                                 expressCycleTime[i]);*/

                location = new VendorLocation();
                location.setPriority( ( priority[i] != null && priority[i].trim().length() != 0) ? priority[i] : "0" );
                location.setLocationName( locationName[i] );
                location.setLocationID( locationID[i] );
                location.setSplit( ( split[i] != null && split[i].trim().length() != 0) ? split[i] : "0" );
                location.setCapacityWeek( ( capacityWeek[i] != null && capacityWeek[i].trim().length() != 0) ? capacityWeek[i] : "0" );
                location.setNormalCost( Float.parseFloat ( ( normalCost[i] != null && normalCost[i].trim().length() != 0) ? normalCost[i] : "0.0" ) );
                location.setExpressCost( Float.parseFloat( expressCost[i] != null && expressCost[i].trim().length() != 0 ? expressCost[i] : "0.0" ) ) ;
                location.setNormalCycleTime(( normalCycleTime[i] != null && normalCycleTime[i].trim().length() != 0) ? normalCycleTime[i] : "0" );
                location.setExpressCycleTime(( expressCycleTime[i] != null && expressCycleTime[i].trim().length() != 0) ? expressCycleTime[i] : "0"  );
                // -- END --
                location.setSelect (select);
                vendorLocations.add (location);
            }
        }
        
        return vendorLocations;
    }

    // Added by hareesh on 27th Septemeber 2003
    // -- START --
    private ArrayList getAllVendorLocations (HttpServletRequest request) {

        ArrayList vendorLocations = new ArrayList();
        String[] locationName = request.getParameterValues("locationName");
        if (locationName == null) {
            return null;
        }
		String[] priority = request.getParameterValues("priority");
		String[] locationID = request.getParameterValues("locationID");;
		String[] split = request.getParameterValues("split");
		String[] capacityWeek = request.getParameterValues("capacityWeek");
		String[] normalCost = request.getParameterValues("normalCost");
		String[] expressCost = request.getParameterValues("expressCost");
		String[] normalCycleTime = request.getParameterValues("normalCycleTime");
		String[] expressCycleTime = request.getParameterValues("expressCycleTime");

        VendorLocation location = null;
        String select = null;

        for (int i=0; i<locationName.length; i++) {

            select = request.getParameter("select_"+i);
            if (select != null) {    // check if this row was enabled by the user or not
                                     // save only if its enabled
                select = "on";
            }else {
                select  = "";
            }

            location = new VendorLocation();
            location.setPriority( ( priority[i] != null && priority[i].trim().length() != 0) ? priority[i] : "0" );
            location.setLocationName( locationName[i] );
            location.setLocationID( locationID[i] );
            location.setSplit( ( split[i] != null && split[i].trim().length() != 0) ? split[i] : "0" );
            location.setCapacityWeek( ( capacityWeek[i] != null && capacityWeek[i].trim().length() != 0) ? capacityWeek[i] : "0" );
            location.setNormalCost( Float.parseFloat ( ( normalCost[i] != null && normalCost[i].trim().length() != 0) ? normalCost[i] : "0.0" ) );
            location.setExpressCost( Float.parseFloat( expressCost[i] != null && expressCost[i].trim().length() != 0 ? expressCost[i] : "0.0" ) ) ;
            location.setNormalCycleTime(( normalCycleTime[i] != null && normalCycleTime[i].trim().length() != 0) ? normalCycleTime[i] : "0" );
            location.setExpressCycleTime(( expressCycleTime[i] != null && expressCycleTime[i].trim().length() != 0) ? expressCycleTime[i] : "0"  );
            location.setSelect (select);
            vendorLocations.add (location);
        }
        return vendorLocations;
    }
    // -- END --
}